package com.totoro.annotation.process;

import com.google.auto.service.AutoService;
import com.squareup.javapoet.*;
import com.totoro.annotation.compile.MyAnnotation;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 自定义编码处理器
 * Created by Niki on 2018/9/29 10:14
 */
@AutoService(Processor.class)
@SupportedAnnotationTypes({"com.totoro.annotation.compile.MyAnnotation"})
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class MyAnnotationProcess extends AbstractProcessor {

    Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);

        // 处理Element的工具类。类的每个部分都是一个特定类型的Element
        Elements elements = processingEnv.getElementUtils();

        // 处理TypeMirror的工具类 Element不包含类的信息，获取类的信息需要通过TypeMirror。
        Types types = processingEnv.getTypeUtils();

        // 处理文件的工具类
        filer = processingEnv.getFiler();

        Messager messager = processingEnv.getMessager();
    }

    @Override
    public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) {
        return super.getCompletions(element, annotation, member, userText);
    }

    /**
     * 自定义注解的处理方法。书写处理注解的逻辑
     * 输入参数RoundEnviroment，可以让你查询出包含特定注解的被注解元素
     *
     * @param annotations 请求处理的注解类型
     * @param roundEnv  当前和以前的环境信息
     * @return 如果返回 true，则这些注解已声明并且不要求后续 Processor 处理它们； 如果返回 false，则这些注解未声明并且可能要求后续 Processor 处理它
     */
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement element : annotations) {
            if (element.getQualifiedName().toString().equals(MyAnnotation.class.getCanonicalName())) {
                System.out.println("------------------------------自动生成类");
                // 创建main方法
                MethodSpec main = MethodSpec.methodBuilder("main")
                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                        .returns(void.class)
                        .addParameter(String[].class, "args")
                        .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
                        .build();

                // 创建属性
                FieldSpec world = FieldSpec.builder(String.class, "word", Modifier.PUBLIC, Modifier.STATIC)
                        .initializer("$S ", "Hello JavaPoet")
                        .build();

//                ParameterSpec world = ParameterSpec.builder(TypeName.OBJECT, "isValid", Modifier.PUBLIC, Modifier.STATIC)
//                        .build();

                // 创建HelloWorld类
                TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
                        .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                        .addMethod(main)
                        .addField(world)

                        .build();


                JavaFile javaFile = JavaFile.builder("com.totoro.annotation.example", helloWorld)
                        .addFileComment("this is a demo class. this codes are generated automatically")
                        .build();
                try {
                    javaFile.writeTo(filer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
}
